package
{
	public class Flow
	{
		/* TODO: add timeout function: panics if a blocked closure is still pending */
		//setTimeout(function():void{debug.print("l="+rom.length)}, 1000);
		/* (?)TODO: add "doInstead(...) function */
		
		private static var held:Array = new Array();
		private static var rep:Array = new Array();
		
		/******* Explicit Hold/Release *******/
		
		/* might need these at some point */
		
		/* Store a blocked closure, released by given string. */
		/*
		public static function Hold(sig:String, op:Function):void {
			held[sig] = op;
		}
		*/
		
		/* Same, with repeats allowed. */
		/*
		public static function HoldRep(sig:String, op:Function):void {
			held[sig] = op;
			rep[sig] = true;
		}
		*/

		/* Releases a stored closure given signal string. */
		/*
		public static function Do(sig:String):void {
			if (held[sig]) {
				(held[sig] as Function).call();
				if (!rep[sig]) {
					delete held[sig];
					delete rep[sig];
				}
			}
		}
		*/
		
		/******* Queueing for in-order execution *******/
		private static var queue:Array = new Array();
		private static var entrant:Boolean = false;
		
		/* Perform asynchronous operation in order. */
		public static function Ord(op:Function):void {
			if ((entrant == true) || (queue.length > 0)) {
				queue.push(op);
			} else {
				entrant = true;
				op.call();
			}
		}
		
		/* Release the next queued operation, if there is one. */
		public static function Next():void {
			entrant = false;
			if (queue.length > 0) {
				entrant = true;
				(queue.shift() as Function).call();
			}
		}
	}
}
